package 
{
	import flash.display.DisplayObjectContainer;
	import flash.display.MovieClip;
	import flash.display.Shape;
	import flash.display.Sprite;
	import flash.display.StageDisplayState;
	import flash.events.Event;
	import flash.events.KeyboardEvent;
	import flash.events.MouseEvent;
	import flash.text.engine.ContentElement;
	import flash.text.engine.ElementFormat;
	import flash.text.engine.FontDescription;
	import flash.text.engine.GroupElement;
	import flash.text.engine.RenderingMode;
	import flash.text.engine.TextBlock;
	import flash.text.engine.TextElement;
	import flash.text.engine.TextLine;
	import flash.text.TextField;
	import flash.text.TextFieldAutoSize;
	import flash.text.TextFieldType;
	import flash.utils.describeType;
	import flash.utils.getTimer;
	import org.osflash.signals.SlotList;
	import org.superkaka.kakalib.optimization.BitmapMovie;
	import org.superkaka.kakalib.utils.BitmapCacher;
	import xxl.ioc.typedescriptions.MethodInjectionPoint;
	import xxl.signals.base.LazySignal;
	import xxl.signals.base.natives.LazyNativeRelaySignal;
	import xxl.signals.base.natives.NativeRelaySignal;
	import xxl.signals.base.natives.NativeSignal;
	import xxl.signals.base.natives.sets.DisplayObjectSignalSet;
	import xxl.signals.base.natives.sets.InteractiveObjectSignalSet;
	import xxl.signals.base.OnceSignal;
	import xxl.signals.base.PrioritySignal;
	import xxl.signals.base.Signal;
	import xxl.signals.base.valuelists.ArrayValueList;
	import xxl.signals.base.valuelists.IntValueList;
	import xxl.signals.core.IOnceSignal;
	import xxl.signals.core.IPrioritySignal;
	import xxl.signals.core.ISignal;
	import xxl.signals.core.natives.INativeDispatcher;
	import org.osflash.signals.natives.INativeDispatcher;
	import org.osflash.signals.natives.NativeSignal;
	import org.osflash.signals.ISignal;
	import org.osflash.signals.Slot;
	import org.osflash.signals.ISlot;
	
	/**
	 * ...
	 * @author XXL
	 */
	public class Main2 extends Sprite 
	{
		private var btn:Sprite = new Sprite();
		private var txt:TextField = new TextField();
		
		public function Main2():void 
		{
			if (stage) init();
			else addEventListener(Event.ADDED_TO_STAGE, init);
		}
		
		private function init(e:Event = null):void 
		{
			removeEventListener(Event.ADDED_TO_STAGE, init);
			
			addChild(txt);
			txt.width = stage.stageWidth;
			txt.autoSize = TextFieldAutoSize.LEFT;
			txt.wordWrap = txt.multiline = true;
			
			// entry point
			//var s:IPrioritySignal = new PrioritySignal(int, int, int);
			//s.addWithPriority(fun3, -100);
			//s.addOnce(fun).params = [999];
			//s.add(fun1);
			//s.addWithPriority(fun2, 100);
			//s.dispatch(1, 2, 3);
			//trace("--------");
			//s.dispatch(1, 2, 3);
			
			//addChild(btn);
			//btn.graphics.beginFill(0xFF0000);
			//btn.graphics.drawRect(0, 0, 100, 100);
			//this.graphics.beginFill(0x00FF00);
			//this.graphics.drawRect(0, 0, 200, 200);
			//stage.addEventListener(MouseEvent.CLICK, cHandler);
			//stage.addEventListener(MouseEvent.CLICK, cHandler2);
			//stage.addEventListener(MouseEvent.CLICK, cHandler3);
			//stage.addEventListener(MouseEvent.CLICK, cHandler4);
			//stage.addEventListener(MouseEvent.CLICK, cHandler5);
			//stage.addEventListener(MouseEvent.CLICK, cHandler6);
			//stage.addEventListener(MouseEvent.CLICK, cHandler7);
			//stage.addEventListener(MouseEvent.CLICK, cHandler8);
			//stage.addEventListener(MouseEvent.CLICK, cHandler9);
			stage.addEventListener(MouseEvent.CLICK, cHandler10);
			
			//var flag:Boolean = (24 % 10) !=
			
			var xml:XML = describeType(Test);
			
			var factoryNode:XMLList = xml.factory;
			trace(factoryNode);
		}
		
		private function cHandler10(e:MouseEvent):void 
		{
			
		}
		
		private var l9:LazyNativeRelaySignal
		private function cHandler9(e:MouseEvent):void 
		{
			if (l9)
			{
				l9.activate();
				return;
			}
			l9 = new LazyNativeRelaySignal(stage, KeyboardEvent.KEY_DOWN, KeyboardEvent);
			l9.add(c9Fun);
		}
		
		private function c9Fun(e:KeyboardEvent):void 
		{
			trace(String.fromCharCode(e.keyCode));
		}
		
		private function cHandler8(e:MouseEvent):void 
		{
			var m:BitmapMovie = new BitmapMovie(BitmapCacher.cacheBitmapMovie(new cls));
			addChild(m);
			m.x = m.y = 100;
			m.play();
			var c:MovieClip = new cls;
			c.x = c.y = 120;
			addChildAt(c, 0);
			c.stop();
			
			var txt:TextField = new TextField();
			txt.type = TextFieldType.INPUT;
			addChild(txt);
			txt.x = txt.y = 100;
			
			var arr:Array = new Array(7);
			trace(arr.length);
			MethodInjectionPoint;
		}
		
		private var set7:DisplayObjectSignalSet;
		private var set7_1:InteractiveObjectSignalSet;
		[Embed(source="../bin/arrow.swf", symbol="ArrowAni")]
		private var cls:Class;
		private function cHandler7(e:MouseEvent):void 
		{
			var s:MovieClip = new cls();
			//s.addFrameScript(1, function():void { trace("aaa"); } );
			//s.addFrameScript(2, function():void { trace("bbb"); } );
			
			//set7 = new DisplayObjectSignalSet(s);
			//set7.added.add(c7Fun);
			//set7.addedToStage.add(c7Fun);
			//set7.addedToStageCapture.add(c7Fun);
			//set7.removed.add(c7Fun);
			//set7.removedFromStage.add(c7Fun);
			//set7.enterFrame.add(c7Fun);
			//set7.exitFrame.add(c7Fun);
			//set7.frameConstructed.add(c7Fun);
			addChild(s);
			stage.displayState = StageDisplayState.FULL_SCREEN;
			var c:Shape = new Shape();
			s.addChild(c);
			stage.removeEventListener(MouseEvent.CLICK, cHandler7);
			var t:TextField = new TextField();
			t.x = 100;
			t.y = 100;
			t.type = TextFieldType.INPUT;
			s.addChild(t);
			t.background = true;
			t.text = "10000";
			//s.removeChild(c);
			//removeChild(s);
			//stage.removeEventListener(MouseEvent.CLICK, cHandler7);
			//stage.addEventListener(MouseEvent.CLICK, c7Click);
			
			//var format:ElementFormat = new ElementFormat();
			//var fontDesc:FontDescription = new FontDescription();
			//fontDesc.renderingMode = RenderingMode.NORMAL;
			//format.fontSize = 24;
			//format.fontDescription = fontDesc;
			//var groupVec:Vector.<ContentElement> = new Vector.<ContentElement>();
			//groupVec.push(new TextElement("中国",format));
			//var groupElement:GroupElement = new GroupElement(groupVec);
			//var textBlock:TextBlock = new TextBlock(groupElement);
			//var textLine:TextLine = textBlock.createTextLine();
			//textLine.x = 100;
			//textLine.y = 100;
			//addChild(textLine);
			set7_1 = new InteractiveObjectSignalSet(s);
			set7_1.textInput.add(c7Fun);
			
		}
		
		private var sprite7:Sprite;
		private function c7Click(e:MouseEvent):void 
		{
			var s:Sprite = new Sprite();
			s.graphics.beginFill(uint(Math.random() * 0xFFFFFF));
			s.graphics.drawRect(0, 0, 100, 100);
			if (sprite7)
			{
				sprite7.addChild(s);
			}
			else
			{
				stage.addChild(s);
				sprite7 = s;
			}
		}
		
		private function c7Fun(e:Event):void 
		{
			trace(e.target, e);
		}
		
		[Embed(source="../bin/arrow.swf", symbol="ArrowAni")]
		private const CLAZZ:Class;
		private function cHandler6(e:MouseEvent):void 
		{
			var mov:MovieClip = new CLAZZ;
			addChild(mov);
			removeAllChildren(mov);
		}
		
		private function removeAllChildren(container:DisplayObjectContainer):void
		{
			if (!container)
			{
				return;
			}
			var mov:MovieClip = container as MovieClip;
			if (mov)
			{
				mov.stop();
			}
			for (var i:int = container.numChildren; i--; )
			{
				var childContainer:DisplayObjectContainer = container.removeChildAt(i) as DisplayObjectContainer;
				if (childContainer)
				{
					removeAllChildren(childContainer);
				}
			}
		}
		
		private function cHandler5(e:MouseEvent):void 
		{
			var i:int;
			var str:String = "";
			var REPS:int = 5000000;
			var time:int;
			var result:Number;
			
			time = getTimer();
			var list1:IntValueList = IntValueList.NIL;
			for (i = 0; i < REPS; i++)
			{
				list1 = list1.prepend(i);
			}
			str += "IntValueList prepend:" + (getTimer() - time) + "\n";
			
			time = getTimer();
			result = 0;
			while (list1.nonEmpty)
			{
				result = list1.head;
				list1 = list1.tail;
			}
			str += "IntValueList (" + result + "):" + (getTimer() - time) + "\n";
			
			//time = getTimer();
			//var list2:ValueList = ValueList.NIL;
			//for (i = 0; i < REPS; i++)
			//{
				//list2 = list2.prepend(i);
			//}
			//str += "ValueList prepend:" + (getTimer() - time) + "\n";
			//
			//time = getTimer();
			//result = 0;
			//while (list2.nonEmpty)
			//{
				//result += list2.head;
				//list2 = list2.tail;
			//}
			//str += "ValueList (" + result + "):" + (getTimer() - time) + "\n";
			
			txt.text = str;
		}
		
		private function cHandler4(e:MouseEvent):void 
		{
			var arr:Array = [1, 2, 3, 4, 5, 6, 7, 8, 9];
			var i:int;
			var str:String = "";
			var REPS:int = 5000000;
			var time:int;
			
			time = getTimer();
			var list1:ArrayValueList = new ArrayValueList(arr);
			for (i = 0; i < REPS; i++)
			{
				list1 = list1.prepend(arr);
			}
			str += "ArrayValueList prepend:" + (getTimer() - time) + "\n";
			
			//time = getTimer();
			//var list2:ValueList = new ValueList(arr);
			//for (i = 0; i < REPS; i++)
			//{
				//list2 = list2.prepend(arr);
			//}
			//str += "ValueList prepend:" + (getTimer() - time) + "\n";
			
			time = getTimer();
			while (list1.nonEmpty)
			{
				arr = list1.head;
				list1 = list1.tail;
			}
			str += "ArrayValueList 遍历:" + (getTimer() - time) + "\n";
			
			//time = getTimer();
			//while (list2.nonEmpty)
			//{
				//arr = list2.head;
				//list2 = list2.tail;
			//}
			//str += "ValueList 遍历:" + (getTimer() - time) + "\n";
			
			txt.text = str;
		}
		
		private var REPS3:int = 100000;
		private function cHandler3(e:MouseEvent):void 
		{
			var l:LazySignal = new LazySignal(int);
			l.add(function():void { } );
			for (var i:int = 0; i < REPS3; i++) 
			{
				l.dispatch(i);
			}
			var str:String = "";
			var time:int = getTimer();
			l.activate();
			str += (getTimer() - time) + "\n";
			time = getTimer();
			//l.activate2();
			str += (getTimer() - time) + "\n";
			txt.text = str;
			REPS3 = REPS3 * 2;
		}
		
		private function cHandler2(e:MouseEvent):void 
		{
			var REPS:int = 50000;
			var i:int = 0;
			var time:int;
			var str:String = "";
			var s:org.osflash.signals.ISignal = new org.osflash.signals.Signal(int);
			
			var index:Array = [];
			var fff1:Array = [];
			var fff2:Array = [];
			for (i = 0; i < REPS; i++)
			{
				if (Math.random() > 0.9)
				{
					index.push(i);
				}
			}
			var slot:ISlot;
			
			time = getTimer();
			slot = new Slot(function():void { }, s);
			var slotList:SlotList = new SlotList(slot);
			for (i = 0; i < REPS; i++)
			{
				if (index.indexOf(i) >= 0)
				{
					fff1.push(function():void { } );
					slot = new Slot(fff1[fff1.length - 1], s);
				}
				else
				{
					slot = new Slot(function():void { }, s);
				}
				slotList = slotList.prepend(slot);
			}
			str += "SlotList add:" + (getTimer() - time) + "\n";
			
			time = getTimer();
			var slotArrs:Array = [];
			for (i = 0; i < REPS; i++)
			{
				if (index.indexOf(i) >= 0)
				{
					fff2.push(function():void { } );
					slot = new Slot(fff2[fff2.length - 1], s);
				}
				else
				{
					slot = new Slot(function():void { }, s);
				}
				slotArrs.push(slot);
			}
			str += "Array add:" + (getTimer() - time) + "\n";
			
			time = getTimer();
			var process:SlotList = slotList;
			if (process && process.nonEmpty)
			{
				while (process.nonEmpty)
				{
					//slot = process.head;
					process.head.execute([]);
					process = process.tail;
				}
			}
			str += "SlotList exe:" + (getTimer() - time) + "\n";
			
			time = getTimer();
			for (i = slotArrs.length; i--; )
			{
				//slot = slotArrs[i];
				slotArrs[i].execute([]);
			}
			str += "Array exe:" + (getTimer() - time) + "\n";
			
			time = getTimer();
			for (i = fff1.length; i--; )
			{
				slotList.find(fff1[i]);
			}
			str += "SlotList find:" + (getTimer() - time) + "\n";
			
			time = getTimer();
			for (i = fff2.length; i--; )
			{
				//slotList.find(fff2[i]);
				//SlotListUtil.Find2(fff2, fff2[i]);
			}
			str += "Array find:" + (getTimer() - time) + "\n";
			
			//time = getTimer();
			//var slots:SlotList = new SlotList(new Slot(function():void { } , s));
			//for (i = 0; i < REPS; i++)
			//{
				//slots = slots.insertWithPriority(new Slot(function():void { } , s));
			//}
			//str += "SlotList insertWithPriority:" + (getTimer() - time) + "\n";
			
			txt.text = str;
		}
		
		private function cHandler(e:MouseEvent):void 
		{
			stage.removeEventListener(MouseEvent.CLICK, cHandler);
			//add time ,execute time
			var REPS:int = 1000;
			var str:String = "";
			var i:int;
			var time:int = getTimer();
			var s:xxl.signals.core.natives.INativeDispatcher = new xxl.signals.base.natives.NativeSignal(stage, MouseEvent.CLICK, MouseEvent);
			for (i = 0; i < REPS; i++) 
			{
				s.add(function(e:*):void { 1 + 1; } );
			}
			str += "ADD xxl nativesignal:" + (getTimer() - time) + "\n";
			
			time = getTimer();
			for (i = 0; i < REPS; i++)
			{
				s.dispatchEvent(new MouseEvent(MouseEvent.CLICK));
			}
			str += "EXE xxl nativesignal:" + (getTimer() - time) + "\n";
			s.removeAll();
			
			time = getTimer();
			s = new xxl.signals.base.natives.NativeRelaySignal(stage, MouseEvent.CLICK, MouseEvent);
			for (i = 0; i < REPS; i++)
			{
				s.add(function(e:*):void { 1 + 1; } );
			}
			str += "ADD xxl nativerelay:" + (getTimer() - time) + "\n";
			
			time = getTimer();
			for (i = 0; i < REPS; i++)
			{
				s.dispatchEvent(new MouseEvent(MouseEvent.CLICK));
			}
			str += "EXE xxl nativerelay:" + (getTimer() - time) + "\n";
			s.removeAll();
			
			time = getTimer();
			var b:org.osflash.signals.natives.INativeDispatcher = new org.osflash.signals.natives.NativeSignal(stage, MouseEvent.CLICK, MouseEvent);
			for (i = 0; i < REPS; i++)
			{
				b.add(function(e:*):void { 1 + 1; } );
			}
			str += "ADD osflash NativeSignal:" + (getTimer() - time) + "\n";
			
			time = getTimer();
			for (i = 0; i < REPS; i++)
			{
				b.dispatchEvent(new MouseEvent(MouseEvent.CLICK));
			}
			str += "EXE osflash NativeSignal:" + (getTimer() - time) + "\n";
			b.removeAll();
			
			time = getTimer();
			b = new org.osflash.signals.natives.NativeRelaySignal(stage, MouseEvent.CLICK, MouseEvent);
			for (i = 0; i < REPS; i++)
			{
				b.add(function(e:*):void { 1 + 1; } );
			}
			str += "ADD osflash NativeRelaySignal:" + (getTimer() - time) + "\n";
			
			time = getTimer();
			for (i = 0; i < REPS; i++)
			{
				b.dispatchEvent(new MouseEvent(MouseEvent.CLICK));
			}
			str += "EXE osflash NativeRelaySignal:" + (getTimer() - time) + "\n";
			b.removeAll();
			
			time = getTimer();
			for (i = 0; i < REPS; i++)
			{
				stage.addEventListener(MouseEvent.CLICK, function(e:*):void { 1 + 1; } );
			}
			str += "ADD addeventlistener:" + (getTimer() - time) + "\n";
			
			time = getTimer();
			for (i = 0; i < REPS; i++)
			{
				stage.dispatchEvent(new MouseEvent(MouseEvent.CLICK));
			}
			str += "EXE addeventlistener:" + (getTimer() - time) + "\n";
			
			time = getTimer();
			for (i = 0; i < REPS; i++)
			{
				stage.addEventListener("哈哈", function(e:*):void { 1 + 1; } );
			}
			str += "ADD addEventListener哈哈:" + (getTimer() - time) + "\n";
			
			time = getTimer();
			for (i = 0; i < REPS; i++)
			{
				stage.dispatchEvent(new Event("哈哈"));
			}
			str += "EXE addeventlistener哈哈:" + (getTimer() - time) + "\n";
			
			time = getTimer();
			var s1:xxl.signals.core.ISignal = new xxl.signals.base.Signal(String);
			for (i = 0; i < REPS; i++)
			{
				s1.add(function(str:String):void { 1 + 1; } );
			}
			str += "ADD Signal哈哈:" + (getTimer() - time) + "\n";
			
			time = getTimer();
			for (i = 0; i < REPS; i++)
			{
				s1.dispatch("哈哈");
			}
			str += "EXE Signal哈哈:" + (getTimer() - time) + "\n";
			
			time = getTimer();
			var b1:org.osflash.signals.ISignal = new org.osflash.signals.Signal(String);
			for (i = 0; i < REPS; i++)
			{
				b1.add(function(str:String):void { 1 + 1; } );
			}
			str += "ADD osflash.Signal哈哈:" + (getTimer() - time) + "\n";
			
			time = getTimer();
			for (i = 0; i < REPS; i++)
			{
				b1.dispatch("哈哈");
			}
			str += "EXE osflash.Signal哈哈:" + (getTimer() - time) + "\n";
			
			time = getTimer();
			s1 = new xxl.signals.base.Signal(int, int, int, int, int);
			for (i = 0; i < REPS; i++)
			{
				s1.add(function(...args):void { 1 + 1; } );
			}
			str += "ADD Signal(5):" + (getTimer() - time) + "\n";
			
			time = getTimer();
			for (i = 0; i < REPS; i++)
			{
				s1.dispatch(1, 2, 3, 4, 5);
			}
			str += "EXE Signal(5):" + (getTimer() - time) + "\n";
			
			time = getTimer();
			b1 = new org.osflash.signals.Signal(int, int, int, int, int);
			for (i = 0; i < REPS; i++)
			{
				b1.add(function(...args):void { 1 + 1; } );
			}
			str += "ADD osflash.Signal(5):" + (getTimer() - time) + "\n";
			
			time = getTimer();
			for (i = 0; i < REPS; i++)
			{
				b1.dispatch(1, 2, 3, 4, 5);
			}
			str += "EXE osflash.Signal(5):" + (getTimer() - time) + "\n";
			
			txt.text = str;
		}
		
		private function fun(v1:int, v2:int, v3:int,v4:int):void
		{
			trace(v1 + v2 + v3, v4);
		}
		
		private function fun1(v1:int, v2:int , v3:int):void
		{
			trace("fun1" , v1);
		}
		
		private function fun2(v1:int, v2:int , v3:int):void
		{
			trace("fun2" , v2);
		}
		
		private function fun3(v1:int, v2:int , v3:int):void
		{
			trace("fun3" , v3);
		}
		
	}
	
}